#[derive(Debug)]
struct Stack<T> {
    items: Vec<T>,
}

impl<T> Stack<T> {
    fn new() -> Self {
        Stack { items: Vec::new() }
    }

    // 入栈
    fn push(&mut self, item: T) {
        self.items.push(item)
    }

    // 出栈
    fn pop(&mut self) -> Option<T> {
        self.items.pop()
    }

    // iter
    fn iter(&self) -> std::slice::Iter<T> {
        self.items.iter()
    }

    // iter_mut
    fn iter_mut(&mut self) -> std::slice::IterMut<T> {
        self.items.iter_mut()
    }

    // into_iter
    fn into_iter(self) -> std::vec::IntoIter<T> {
        self.items.into_iter()
    }
}

fn main() {
    // 以下三种不同的迭代器类型，都是基于Iterator特质实现，Iterator特质上提供很多方法用来处理序列，Iter、IntoIter、Chars类型上都实施了Iterator特质

    // IntoIter
    let v = vec![1, 2, 3, 4, 5];
    // 调用into_iter方法，会发生所有权转移
    let v_iter = v.into_iter();
    let v_sum = v_iter.sum::<i32>();
    println!("vec sum: {}", v_sum);

    // Iter
    let a = [1, 2, 3, 4, 5];
    // 调用iter方法，所有权不会转移
    let a_iter = a.iter();
    let a_sum = a_iter.sum::<i32>();
    println!("array sum: {}", a_sum);

    // Chars
    let s = "rust";
    let s_iter = s.chars();
    let s_new = s_iter.map(|c| c.to_ascii_uppercase()).collect::<String>();
    println!("&str uppercase: {}", s_new);

    // 获取迭代器三种方法

    // iter()方法，返回一个不可变引用迭代器
    let vec = vec![1, 2, 3, 4, 5];
    for item in vec.iter() {
        println!("{}", item);
    }
    println!("{:?}", vec);

    // iter_mut()方法，返回一个可变引用迭代器，修改集合本身，性能很差
    let mut vec = vec![1, 2, 3, 4, 5];
    for item in vec.iter_mut() {
        *item *= 2;
    }
    println!("{:?}", vec);

    // into_iter()方法，返回一个所有权转移迭代器，消耗集合本身转移迭代器，用得多
    let vec = vec![1, 2, 3, 4, 5];
    for item in vec.into_iter() {
        println!("{}", item);
    }
    // 以下打印是过不了编译的，也就说明所有权被转移了
    // println!("{:?}", vec);

    // 在结构体上，自定义迭代器三种方法
    let mut stack = Stack::new();
    stack.push(1);
    stack.push(2);
    stack.push(2);

    for item in stack.iter() {
        println!("{}", item)
    }
    println!("{:?}", stack);

    for item in stack.iter_mut() {
        *item *= 2;
        println!("{}", item)
    }
    println!("{:?}", stack);

    for item in stack.into_iter() {
        println!("{}", item)
    }
    // 同上，这里的所有权转移，下面代码无法执行
    // println!("{:?}", stack);

    /*
     * 消费者适配器
     *   1.方法内部调用了next方法，消耗迭代器上元素，拿掉迭代器所有权
     *   2.常见的消费者适配器有：sum、collect、count、find、any、all等
     *   3.collect方法，将迭代器元素收集到集合中，返回集合，且可以指定集合类型
     */
    let v = vec![1, 2, 3, 4, 5];

    // 调用iter方法，借用v的不可变引用，返回一个迭代器
    let v_iter = v.iter();

    println!("v_iter: {:?}", v_iter);

    let v_sum = v_iter.sum::<i32>();

    println!("v_sum: {}", v_sum);

    // 这里v_iter已经被消费，无法再次使用，所以无法打印
    // println!("v_iter: {}", v_iter);

    /*
     * 迭代器适配器
     *   1.迭代器适配器是惰性的，需要通过消费者迭代器来收尾
     *   2.常见的迭代器适配器有：map、filter、enumerate、skip、take、chain、zip等
     */
    let v = vec![1, 2, 3, 4, 5];

    let v_sum = v
        .iter()
        .zip(v.iter().skip(1))
        .map(|(a, b)| a * b)
        .filter(|x| x % 2 == 0)
        .sum::<i32>();

    println!("v_sum: {}", v_sum);

    for (v, k) in v.iter().enumerate() {
        println!("index: {}, value: {}", v, k);
    }
}
